import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

/**
 * 阻塞队列(也是集合)：
 * 队列为空，取数据会被阻塞
 * 队列满，添加数据会被阻塞
 * 架构：
 * collection -》 queue -》BlockingQueue
 * 7种实现类：
 * ArrayBlockingQueue 有界
 * LinkedBlockingQueue 有界
 * LinkedBlockingDeque(双端阻塞队列)
 * SynchronousQueue（不会存储，单个阻塞队列）
 * 4类api:
 * <p>
 * 插入： add       offer    put     offer(e,time,unit)
 * 移除： remove    poll     take    poll(time,unit)
 * 检查： element   peek     不可用   不可用
 * （超过队列长度，直接抛出异常）
 * 成功返回true，失败返回false，不会抛出异常
 * 队列满了，会阻塞当前线程;队列空了，也会阻塞
 * 队列满了，会阻塞当前线程，超过指定时间会退出阻塞;队列空了，也会阻塞超过指定时间会退出阻塞
 */

public class BlockingQueueDemo {

    public static void main(String[] args) throws InterruptedException {
        // 需要初始长度
        ArrayBlockingQueue<Integer> integers = new ArrayBlockingQueue<Integer>(3);
        integers.add(1);
        integers.add(2);
        integers.add(3);
//        integers.add(4); java.lang.IllegalStateException: Queue full
        integers.remove();
        integers.remove();
        integers.remove();
        //integers.remove();报异常
        System.out.println("====================================");

        integers.offer(1, 2L, TimeUnit.SECONDS);
        integers.offer(2, 2L, TimeUnit.SECONDS);
        integers.offer(3, 2L, TimeUnit.SECONDS);
        integers.offer(4, 2L, TimeUnit.SECONDS);
    }
}


class SysQueueDemo {

    public static void main(String[] args) {

        SynchronousQueue<Integer> integers = new SynchronousQueue<>();

        new Thread(() -> {

            try {
                product(integers.offer(1, 2L, TimeUnit.SECONDS));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }, "productor").start();

        new Thread(() -> {

            try {
                consumer(integers.poll(2L, TimeUnit.SECONDS));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }, "consumer").start();
    }

    public static void product(boolean offer) {
        System.out.println(Thread.currentThread().getName() + " 生产 " + offer);
    }

    public static void consumer(Integer poll) {
        System.out.println(Thread.currentThread().getName() + " 消费 " + poll);
    }
}